﻿using System;
using System.Collections.Generic;
using System.Text;

namespace KnBinarySerializer
{
    internal class RuningTypeFormatter : IFormatter
    {
        public Type GetHandleType()
        {
            return null;
        }
        public bool IsFixLen()
        {
            return false;
        }
        public byte GetKey()
        {
            return 3;
        }

        public object ReadBytes(BianaySerializeManager content, int maxLen, Type type)
        {
            byte key = content.ReadByte();
            if (key == BianaySerializeManager.CLASS_FORMATTER_KEY)
            {
                string fullName = content.DeSerializeObject<string>();
                Type runType = Type.GetType(fullName);
                if (runType == null && !string.IsNullOrEmpty(fullName))
                    throw new Exception($"生成类型时出错，无法获取以下类型：{fullName}");
                return runType;
            }
            else
            {
                IFormatter formatter = content.GetFormatter(key);
                if (formatter == null)
                    throw new Exception($"生成类型时出错，不支持的key：{(int)key}");
                return formatter.GetHandleType();
            }
        }

        public int WriteBytes(BianaySerializeManager serial, object obj)
        {
            Type runType = (Type)obj;
            long start = serial.GetPosition();
            IFormatter formatter = serial.GetFormatter(runType);
            serial.Write(formatter.GetKey()); //写入key
            //如果是Class需要使用其全称
            if (formatter.GetKey() == BianaySerializeManager.CLASS_FORMATTER_KEY)
            {
                string fullName = runType.FullName;
                string[] arr = runType.Assembly.FullName.Split(',');
                fullName = $"{runType.FullName},{arr[0]}";//不要版本号等信息，只是名字。

                //在服务端与客户端运行框架不一致时，有可能以下全称无法创建类型。
                //如DataTable，在net40是System.Data.DataTable,System.Data
                //            ，在net6是System.DataTable,System.Data.Common
                //不过，因为DataTable是一个专门的Formatter，所有不会跑到这里。所以DataTable不会有这个问题。
                //以上只是举例
                serial.SerializeObject(fullName);
            }
            return serial.GetLength(start);
        }
    }
}
